package org.loong.crypto.service.software.provider.asymmetric.dsa;

import java.security.interfaces.DSAPrivateKey;

import org.loong.crypto.common.exception.CryptoException;
import org.loong.crypto.common.exception.InvalidKeyException;
import org.loong.crypto.core.algorithm.SignatureAlgorithm;
import org.loong.crypto.core.utils.DSAKeyUtils;
import org.loong.crypto.service.core.provider.Signer;
import org.loong.crypto.service.core.provider.impl.DSAProvider;

import cn.hutool.crypto.asymmetric.Sign;

/**
 * DSA signer of data.
 */
public class DSASigner extends DSAProvider implements Signer {

    /**
     * The private key.
     */
    private DSAPrivateKey privateKey;

    /**
     * Creates a new signer.
     *
     * @param keyBytes the private key bytes. Must not be {@code null}.
     */
    public DSASigner(final byte[] keyBytes) {
        this(DSAKeyUtils.toDSAPrivateKey(keyBytes));
    }

    /**
     * Creates a new signer.
     *
     * @param privateKey the private key. Must not be {@code null}.
     */
    public DSASigner(final DSAPrivateKey privateKey) {
        if (privateKey == null) {
            throw new InvalidKeyException("The private DSA key must not be null.");
        }

        if (!"DSA".equalsIgnoreCase(privateKey.getAlgorithm())) {
            throw new InvalidKeyException("The private key algorithm must be DSA.");
        }

        this.privateKey = privateKey;
    }

    @Override
    public byte[] sign(final SignatureAlgorithm algorithm, final byte[] data) throws CryptoException {
        try {
            Sign signature = new Sign(algorithm.getName(), privateKey, null);
            return signature.sign(data);
        } catch (cn.hutool.crypto.CryptoException e) {
            throw new CryptoException("DSA signature exception: " + e.getMessage(), e);
        }
    }
}
